昨日簡單創建完專案後,我們今天簡單的看一下專案架構
我們能看到Tauri專案主要分為src和src-tauri
folder directory:
1.src directory:
用於開發並且顯示畫面,主要是跟使用者互動,並將操作結果以籍資料傳輸到tauri內部去做處理
2.src-tauri directory:
主要是app內部功能,類似於後端,進行一些邏輯以及資料的處理,並且能與系統平台相互動
tauri.conf.json
主要是用來設定app的一些功能,像是window大小,以及是否能resize,或者是build的設定
我們試著觀察todo\src\pages
裡的index.tsx
import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
import Image from "next/image";
import reactLogo from "../assets/react.svg";
import tauriLogo from "../assets/tauri.svg";
import nextLogo from "../assets/next.svg";
function App() {
const [greetMsg, setGreetMsg] = useState("");
const [name, setName] = useState("");
async function greet() {
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
setGreetMsg(await invoke("greet", { name }));
}
return (
<div className="container">
<h1>Welcome to Tauri!</h1>
<div className="row">
<span className="logos">
<a href="https://nextjs.org" target="_blank">
<Image
width={144}
height={144}
src={nextLogo}
className="logo next"
alt="Next logo"
/>
</a>
</span>
<span className="logos">
<a href="https://tauri.app" target="_blank">
<Image
width={144}
height={144}
src={tauriLogo}
className="logo tauri"
alt="Tauri logo"
/>
</a>
</span>
<span className="logos">
<a href="https://reactjs.org" target="_blank">
<Image
width={144}
height={144}
src={reactLogo}
className="logo react"
alt="React logo"
/>
</a>
</span>
</div>
<p>Click on the Tauri, Next, and React logos to learn more.</p>
<div className="row">
<div>
<input
id="greet-input"
onChange={(e) => setName(e.currentTarget.value)}
placeholder="Enter a name..."
/>
<button type="button" onClick={() => greet()}>
Greet
</button>
</div>
</div>
<p>{greetMsg}</p>
</div>
);
}
export default App;
我們看到了一個greet():
async function greet() {
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
setGreetMsg(await invoke("greet", { name }));
}
我們能看到他呼叫了invoke這個method,而這個invoke(),試著與tauri內部進行溝通的函式,然後我們看到他呼叫了內部greet這個方法
setGreetMsg(await invoke("greet", { name }));
接著,我們打開todo\src-tauri\src\main.rs
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
能看到greet這個方法,輸入name後會傳回一個字串
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
接下來我們測試一下,嘗試修改todo\src\pages\index.tsx
為:
import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
function App() {
return (
<div className="container">
<h1>Welcome to Todo List</h1>
</div>
);
}
export default App;
接下來,我們簡單實作Todo List
import { useState } from "react";
import { invoke } from "@tauri-apps/api/tauri";
const itemStyle = {
padding: '8px',
};
function App() {
const [todos, setTodos] = useState<string[]>([]);
const [todo, setTodo] = useState("");
const handleTaskAdd = async () => {
setTodos([todo, ...todos]);
setTodo('');
}
const handleTaskDelete = async (index) => {
setTodos(todos.filter(e => e !== todos[index]));
setTodo('');
}
return (
<div className="container">
<h1>Welcome to Todo List</h1>
<div className="row">
<input
id="greet-input"
onChange={(e) => setTodo(e.currentTarget.value)}
placeholder="Enter a task..."
value={todo}
/>
<button type="button" onClick={() => handleTaskAdd()}>
Add
</button>
</div>
<hr />
{todos.map((todo, index) => {
return (
<div className="row" key={index}>
<div style={itemStyle}>{todo}</div>
<button type="button" onClick={() => handleTaskDelete(index)}>
Delete
</button>
</div>
);
})}
</div>
);
}
export default App;
今天我們再畫面上成功創建一個簡單的todo,接下來的任務就是將資料傳遞至tauri內部。在明天開始撰寫前,我們先簡單的講解下rust